/**
 * FILE:  SearchParameterSetEditingUI.js
 *
 * Part of the Metavus digital collections platform
 * Copyright 2016-2021 Edward Almasy and Internet Scout Research Group
 * http://metavus.net
 *
 * Javascript routines for the SearchParameterSetEditingUI.
 * @scout:eslint
 */

(function(){
    /**
    * Toggle UI elements such that only those appropriate for a
    * selected field are visible.
    * @param subjectField HTML form field selecting which metadata
    *   field should be in use.
    */
    function modifySiblingFields(subjectField) {
        var topRow = subjectField.parent().parent().children();
        showAppropriateEditFields( topRow );
    }

    /**
    * Toggle UI elements to show only appropriate edit fields for a selected field.
    * @param field-row <tr> containing the elements to consider.
    */
    function showAppropriateEditFields(field_row) {
        var subj_field = jQuery('.field-subject', field_row),
            valueSelectField = jQuery('.field-value-select', field_row),
            valueEditField = jQuery('.field-value-edit', field_row),
            valueQSField = jQuery('.mv-quicksearch', field_row),
            field_type = jQuery(":selected",subj_field).attr("class").match(/field-type-[a-z]+/),
            field_id = jQuery(":selected", subj_field).attr("value");

        if (field_type == "field-type-flag" || field_type == "field-type-option") {
            valueSelectField.show();
            valueEditField.hide();
            valueQSField.hide();

            // stash a copy of the default options to use whenever the
            // selection is changed
            if (!valueSelectField.data("default-options")){
                valueSelectField.data("default-options", valueSelectField.html());
            }
            // reset option values to the defaults
            valueSelectField.html("").append(valueSelectField.data("default-options"));
            // then remove any option values not appropriate for this field
            jQuery("option:not(.field-id-"+field_id+")", valueSelectField).remove();

        } else if (field_type == "field-type-controlledname" ||
                   field_type == "field-type-tree" ||
                   field_type == "field-type-reference") {
            valueQSField.show();
            valueQSField.attr("data-fieldid", field_id);

            // if the current field has a quicksearch setup, remove it
            //  otherwise, create one
            if (valueQSField.hasClass('mv-quicksearch-template')) {
                valueQSField.removeClass('mv-quicksearch-template');
            } else {
                $('.mv-quicksearch-display', valueQSField).autocomplete("destroy");
            }

            // and set up a new quicksearch widget using the right field
            QuickSearch(valueQSField); // eslint-disable-line no-undef

            valueEditField.hide();
            valueSelectField.hide();
        } else {
            valueEditField.show();
            valueSelectField.hide();
            valueQSField.hide();
        }
    }

    /**
    * Handle clicks on the 'Add Field' button.
    * (defined as named function so that we can attach it as a click()
    * handler inside newly added subgroups)
    */
    function handleAddFieldClick() {
        // grab the template row
        var tpl_row = $(this).parent().parent().prev();

        // make a copy of it, set the copy visible
        var new_row = tpl_row.clone(true);
        new_row.removeClass('template-row');
        tpl_row.before(new_row);
        new_row.show();
    }

    /**
    * Handle clicks on the 'Add Subgroup' button.
    * (defined as named function so that we can attach it as a click()
    * handler inside newly added subgroups)
    */
    function handleAddSubgroupClick() {
        // grab the template row
        var tpl_row = $(this).parent().parent().prev();

        // make a copy of it, copying event handlers
        var new_row = tpl_row.clone(true);
        var new_placeholder = tpl_row.clone(true);

        // remove the template-row class from our clone
        new_row.show();
        new_row.removeClass('template-row');

        // get the form name out of our template row
        var form_name = $(".field-subject", new_row).attr("name");

        // construct the HTML for a new subgroup table
        var new_table = $(
            '<tr><td colspan=2 style="padding-left: 2em;">' +
            '<input type="hidden" name="'+form_name+'" value="X-BEGIN-SUBGROUP-X"/>' +
            '<table class="mv-sepui-subgroup">' +
            '<tr class="logic_row ">' +
            '<td colspan="3">Subgroup with ' +
            '<select name="'+form_name+'" class="logic">' +
            '<option value="AND">AND</option>' +
            '<option value="OR" selected>OR</option>' +
            '</select> Logic</td></tr>' +
            '<tr class="mv-jq-placeholder-1"></tr>' +
            '<tr class="mv-jq-placeholder-2"></tr>' +
            '<tr><td colspan="2">' +
            '<span class="btn btn-primary btn-sm ' +
            'mv-speui-add">Add Field</span>' +
            '<span class="btn btn-primary btn-sm ' +
            'mv-speui-add-subgroup">Add Subgroup</span>'+
            '</td></tr></table>' +
            '<input type="hidden" name="'+form_name+'" value="X-END-SUBGROUP-X"/>' +
            '</td></tr>');

        // stuff our cloned template into the new table
        $(".mv-jq-placeholder-1", new_table).replaceWith(new_row);
        $(".mv-jq-placeholder-2", new_table).replaceWith(new_placeholder);

        // hook up the add button handlers
        $(".mv-speui-add", new_table).click(handleAddFieldClick);
        $(".mv-speui-add-subgroup", new_table).click(handleAddSubgroupClick);

        // insert the new table before our template row
        tpl_row.before(new_table);
    }

    // do UI setup
    $(document).ready(function(){
        var subjectFields = jQuery(".field-subject:not(.field-static)");

        // hide elements that should be hidden
        subjectFields.each(function(){
            showAppropriateEditFields(jQuery(this).parent().parent().children());
        });
        jQuery(".template-row").hide();

        // watch for subject changes, alter field hiding as needed
        subjectFields.change( function(){
            // grab our table row
            var row = jQuery(this).parent().parent();

            // clear any error fields and remove error messages
            jQuery('.field-value-edit', row).removeClass('mv-form-error');
            jQuery('span.mv-speui-error', row).remove();

            // clear edit/replace values
            jQuery('.field-value-edit', row).attr('value','');
            jQuery('.field-value-repl', row).attr('value','');

            // rearrange visiable fields as needed
            modifySiblingFields( jQuery(this) );
        });

        // handle clicking add subgroup button
        jQuery(".mv-speui-add").click(handleAddFieldClick);
        jQuery(".mv-speui-add-subgroup").click(handleAddSubgroupClick);

        // handle clicking the delete button
        jQuery(".mv-speui-delete").click(function(){
            // get the row we belong to
            var tgt_row = $(this).parent().parent();

            // and then get the table we belong to
            var parent_table = $(tgt_row).parentsUntil("table").last().parent();

            // remove our target row
            $(tgt_row).remove();

            // if this was a subgroup, and it is now empty, then remove it
            while (parent_table.hasClass("mv-speui-subgroup")  &&
                   jQuery('.field-row:not(.template-row)', parent_table).length == 0) {
                // save our current target
                var tgt = parent_table;

                // look up the table that contains this target
                parent_table = $(parent_table).parentsUntil("table").last().parent();

                // nuke the targeted subgroup
                $(tgt).parent().parent().remove();
            }
        });

        jQuery(".mv-speui-form").submit(function() {
            // if everything was okay, remove the template rows before submission
            jQuery(".template-row").remove();

            // make sure that every select contains something to avoid parse problems
            jQuery(".field-value-select:empty").append(
                '<option value="0">--</option>');
        });
    });
}());
